package cht;

import java.awt.Color;
import robocode.BulletHitEvent;
import robocode.BulletMissedEvent;
import robocode.HitByBulletEvent;
import robocode.Robot;
import robocode.ScannedRobotEvent;
import static robocode.util.Utils.normalRelativeAngleDegrees;

/**
 * Contains the Narchi Robocode Robot.
 * 
 * @author Terrence Chida
 * 
 */
public class Narchi extends Robot {

  double bulletPower = 1;
  boolean hitEnemy;

  /**
   * Begin execution. Move to closest corner, keep spinning until the end.
   */
  @Override
  public void run() {
    setBulletColor(Color.CYAN);
    setRadarColor(Color.WHITE);
    setScanColor(Color.WHITE);
    moveToClosestCorner();
    turnRight(Double.POSITIVE_INFINITY);
  } // end run()

  /**
   * If a robot is found, lock onto it and fire.
   * 
   * @param e The event triggered when a robot is scanned.
   */
  @Override
  public void onScannedRobot(ScannedRobotEvent e) {
    double absoluteBearing = getHeading() + e.getBearing();
    double bearingFromGun = normalRelativeAngleDegrees(absoluteBearing - getGunHeading());
    turnGunRight(bearingFromGun);
    if (getGunHeat() == 0) {
      // if we hit an enemy, increase fire power.
      if (this.hitEnemy) {
        this.bulletPower += 0.5;
      }
      // if we miss an enemy, decrease fire power.
      else {
        this.bulletPower -= 0.5;
      }
      fire(this.bulletPower);
    }
    // follows the enemy
    if (bearingFromGun == 0) {
      scan();
    }

  } // end onScannedRobot()

  /**
   * Increase the bullet power if we shot an enemy.
   * 
   * @param e Not used.
   */
  @Override
  public void onBulletHit(BulletHitEvent e) {
    this.hitEnemy = true;
  }

  /**
   * Decrease the bullet power if we shot and missed an enemy.
   * 
   * @param e Not used.
   */
  @Override
  public void onBulletMissed(BulletMissedEvent e) {
    this.hitEnemy = false;
  }

  /**
   * Called when Narchi is hit by a bullet. Move in a random direction and continue scanning.
   * 
   * @param e Information on the current state of the battle.
   */
  @Override
  public void onHitByBullet(HitByBulletEvent e) {
    double absoluteBearing = getHeading() + e.getBearing();
    double bearingFromGun = normalRelativeAngleDegrees(absoluteBearing - getGunHeading());
    turnLeft(e.getBearing() + 100);
    ahead(200);
    turnRight(360);
    turnGunRight(bearingFromGun);
    if (getGunHeat() == 0) {
      if (this.hitEnemy) {
        this.bulletPower += 0.5;
      }
      else {
        this.bulletPower -= 0.5;
      }
      fire(this.bulletPower);
    }
    ahead(50);
  }

  /**
   * Move to the corner defined by the quadrant that Narchi starts off in.
   */
  public void moveToClosestCorner() {
    // upper half
    if (getY() >= (getBattleFieldHeight() / 2.0)) {
      // face 180 (South)
      turnLeft(getHeading() - 180);
      back(getBattleFieldHeight() - getY());
      setAdjustGunForRobotTurn(true);
      // upper-right quadrant
      if (getX() >= (getBattleFieldWidth() / 2.0)) {
        turnRight(90);
        // now facing West, gun facing South
        back(getBattleFieldWidth() - getX());
        turnGunRight(360);
      }
      // upper-left quadrant
      else {
        turnLeft(90);
        // now facing East, gun facing South
        back(getX());
        turnGunLeft(360);
      }
    }
    // bottom half
    else {
      // face North
      turnLeft(getHeading());
      back(getY());
      setAdjustGunForRobotTurn(true);
      // bottom-right quadrant // bottom-right quadrant
      if (getX() >= (getBattleFieldWidth() / 2.0)) {
        turnLeft(90);
        // now facing West, gun facing North
        back(getBattleFieldWidth() - getX());
        turnGunRight(360);
      }
      // bottom-left quadrant
      else {
        turnRight(90);
        // now facing East, gun facing North
        back(getX());
        turnGunLeft(360);
      }
    }
    setAdjustGunForRobotTurn(false);
  } // end moveToClosestCorner()

} // end Narchi()
